package com.thread.threadfirst.SpringThreadPool;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;

/**
 * 异步方法的异常处理
 */
@Component
public class AsyncExceptionDemo {
    private static final Logger logger = LoggerFactory.getLogger(AsyncDemo.class);

    /**
     * 最简单的异步调用，返回值为void
     */
    @Async
    public void asyncInvokeSimplest() {
        logger.info("asyncInvokeSimplest");
    }

    /**
     * 带参数的异步调用 异步方法可以传入参数
     * 对于返回值是void，异常会被AsyncUncaughtExceptionHandler处理掉
     *
     * @param s
     */
    @Async
    public void asyncInvokeWithParameter(String s) {
        logger.info("asyncInvokeWithParameter,param={}", s);
        throw new IllegalArgumentException("test");  //注意：throw new XXXException("XXX"); 此处的XXXException不能是Exception这个父类，必须是Exception的子类。
        //简单的异常处理，可以在此方法中直接catch exception。而实现了AsyncConfigurer接口的类中的AsyncUncaughtExceptionHandler 是个更细腻的异常处理，会显示异常方法的方法名、参数、抛出的异常信息。
//        try {
//            logger.info("asyncInvokeWithParameter,param={}",s);
//            throw new IllegalArgumentException(s);  //注意：throw new XXXException("XXX"); 此处的XXXException不能是Exception这个父类，必须是Exception的子类。
//        }catch (Exception e){
//            logger.info("error");
//        }

    }

    /**
     * 异常调用返回Future 异步回调
     * 对于返回值是Future，不会被AsyncUncaughtExceptionHandler处理，需要我们在方法中捕获异常并处理
     * 或者在调用方在调用Futrue.get时捕获异常进行处理
     *
     * @param i
     * @return
     */
    @Async
//    @Async("myThreadPool")
//    @Async("getAsyncExecutor")
    //注意此处括号中的线程池名是自定义线程池的方法名(因为默认会以方法名来定义Bean的名字，当然也可以@Bean(name = "XXX")这样来自定义名字) 不是自定义线程池的线程名称前缀。
//    @Async("taskExecutor")
    public Future<String> asyncInvokeReturnFuture(int i) {
        logger.info("asyncInvokeReturnFuture,param={}", i);
        Future<String> future = null;
        try {
            Thread.sleep(1000 * 1);
            future = new AsyncResult<String>("success" + i);
            throw new IllegalArgumentException("a");  //此处的异常出现后，如果有下方的catch，就不会打印出冗长的异常信息而是被catch块中的操作代替 比如如果catch中有logger.error("");就会将此信息代替掉冗长的异常信息。
        } catch (InterruptedException e) {
//            e.printStackTrace();
            future = new AsyncResult<String>("error");
        } catch (IllegalArgumentException e) {
            future = new AsyncResult<>("error-IllegalArgumentException");
        }
        return future;
    }

    @Async
    public Future<List<String>> test() {
        List<String> list = new ArrayList();
        list.add("a");
        list.add("b");
        return new AsyncResult<List<String>>(list);
    }
}
